#include "esp8266.hpp"

WiFiClient espClient;                        // Wifi客户端对象
PubSubClient mqttclient(espClient);          // MQTT客户端对象
esp_config_t esp_config;                     // 网络配置的结构体

/**
 * 保存配置到EEPROM
 */
void esp_saveconfig()
{
    EEPROM.begin(sizeof(esp_config) + 2);
    EEPROM.write(0, 0x22);                     // 标识符1
    EEPROM.write(1, 0xDD);                     // 标识符2
    EEPROM.put(2, esp_config);
    EEPROM.commit();
    EEPROM.end();
    mqttclient.disconnect();
    WiFi.disconnect();
    Serial.println("[SYS] 配置数据已保存");
}

/**
 * 从EEPROM中读取配置
 */
void esp_readconfig()
{
    EEPROM.begin(sizeof(esp_config) + 2);
    if (EEPROM.read(0) == 0x22 && EEPROM.read(1) == 0xDD)        // 检查两个标识符
    {
        EEPROM.get(2, esp_config);
    }
    else
    {
        memset(static_cast<void *>(&esp_config), 0, sizeof(esp_config));
        esp_config.mqtt_port = 1883;            // 默认MQTT端口
        esp_config.stopped = 1;                 // 默认状态停止
    }
    EEPROM.end();
}

/**
 * ESP8266初始化
 */
void esp_init()
{
    delay(500);
    esp_readconfig();                           // 预配置信息
    esp_webserver_init();                       // 初始化Web服务器
    WiFi.mode(WIFI_AP_STA);                     // 配置WiFi模式
    WiFi.softAP("ESP8266", "12345678");
    Serial.println("[SYS] ESP8266 MQTT网关");
}

/**
 * 连接WiFi
 */
bool esp_wificonnect()
{
    if (WiFi.status() == WL_CONNECTED)                  // 检查初始状态
    {
        return true;
    }
    WiFi.mode(WIFI_AP_STA);
    WiFi.softAP("ESP8266", "12345678");
    WiFi.begin(esp_config.wifi_ssid, esp_config.wifi_password);     // 连接配置的WiFi
    // WiFi.begin("KARMEN", "12345678");

    int attempts = 0;
    const int maxAttempts = 10;

    Serial.print("[SYS] Wifi开始连接...");
    while (WiFi.status() != WL_CONNECTED && attempts < maxAttempts)
    {
        delay(1000);
        Serial.print(".");
        attempts++;
    }
    Serial.println();
    if (WiFi.status() != WL_CONNECTED)
    {
        Serial.println("[SYS] Wifi连接失败");
        return false;
    }
    Serial.println("[SYS] Wifi连接成功,IP:" + WiFi.localIP().toString());
    return true;
}

/**
 * MQTT信息回调函数
 */
void callback(char *topic, byte *payload, unsigned int length)
{
    String message;
    for (unsigned int i = 0; i < length; i++)
    {
        message += (char)payload[i];
    }
    Serial.println("[DAT] " + message);
}

/**
 * 连接MQTT
 */
bool esp_mqttconnect()
{
    if (mqttclient.connected())
    {
        return true;
    }
    Serial.println("[SYS] MQTT开始连接...");
    String clientId = "ESP8266Client-";                 // 生成随机客户端ID
    clientId += String(random(0xffff), HEX);
    mqttclient.setServer(esp_config.mqtt_server, esp_config.mqtt_port);
    // 尝试连接MQTT
    if (mqttclient.connect(clientId.c_str(), esp_config.mqtt_user, esp_config.mqtt_password))
    {
        Serial.println("[SYS] MQTT连接成功");
        mqttclient.setCallback(callback);                      // 设置信息回调
        mqttclient.subscribe(esp_config.mqtt_sub_topic);       // 订阅主题
        return true;
    }
    else
    {
        Serial.println("[SYS] MQTT连接失败");
        return false;
    }
}

/**
 * 串口数据接收处理
 */
void esp_receive()
{
    if (Serial.available() > 0)
    {
        String dat = Serial.readStringUntil('\n');
        if (dat.endsWith("\r"))
        {
            dat = dat.substring(0, dat.length() - 1);           // 去除回车符
        }
        const char *res = dat.c_str();

        // 处理发布命令: p 主题 消息
        if (*res == 'p')
        {
            if (mqttclient.connected())
            {
                mqttclient.publish(esp_config.mqtt_pub_topic, res + 2);
                Serial.println("[SYS] 发布成功" + String(res + 2));
            }
            else
            {
                Serial.println("[SYS] 发布失败" + String(res + 2));
            }
        }
        // 处理停止命令
        else if (dat == "c:stop"){
            esp_config.stopped=1;
            mqttclient.disconnect();
            WiFi.disconnect();
        }
        // 处理启动命令
        else if (dat == "c:start"){
            esp_config.stopped=0;
            mqttclient.disconnect();
            WiFi.disconnect();
        }
        else
        {
            Serial.println("[SYS] 未知命令" + dat);
        }
    }
}

/**
 * 主运行函数
 */
void esp_running()
{
    esp_receive();
    esp_webserver_running();
    if (!esp_config.stopped)
    {
        if (esp_wificonnect())
        {
            if (esp_mqttconnect())
            {
                mqttclient.loop();
            }
        }
    }
}
